import { Component, Vue } from 'vue-property-decorator';
import style from '@/styles/views/gas.module.less';
import { Window } from '@/components';
import {
  Button,
  Cell,
  CellGroup,
  Dialog,
  Icon,
  NavBar,
  PullRefresh,
  Radio,
  RadioGroup,
  Slider,
  SwipeCell,
  Switch
} from 'vant';
import { IDeviceType, ISimpleDevice } from '@/interfaces/device.interface';
import { gasPng, windowIconPng } from '../assets';
import { IResponse } from '@/interfaces/api.interface';
import { edger } from '@edgeros/web-sdk';

interface IInitData {
  window_percent: number;
}

const GAS_VALUE_RANGE: any = {
  // 气体取值区间
  co: [0, 500],
  ch2o: [0, 3],
  c2h5oh: [0, 300],
  tvoc: [0, 20],
  ch4: [0, 10000]
};

const GAS_DEFAULT_ALARM_VALUES = {
  // 气体检测默认警告值
  co: 100,
  ch2o: 0.5,
  c2h5oh: 50,
  tvoc: 0.5,
  ch4: 3000
};

// type IGasType = 'co' | 'ch2o' | 'c2h5oh' | 'tvoc' | 'ch4';

interface ISceneDevice extends ISimpleDevice {
  real_value: number;
  alarm_value?: number;
}

Vue.use(Dialog);

@Component({
  components: {
    window: Window,
    'van-nav-bar': NavBar,
    'van-button': Button,
    'van-radio-group': RadioGroup,
    'van-radio': Radio,
    'van-cell-group': CellGroup,
    'van-cell': Cell,
    'van-slider': Slider,
    'van-switch': Switch,
    'van-swipe-cell': SwipeCell,
    'van-pull-refresh': PullRefresh,
    'van-icon': Icon
  },
  sockets: {
    connect() {
      // 说明是断线重连
      this.$socket.client.emit('init', (data: IInitData) => {
        this.$data.window_percent = data.window_percent;
      });
    },
    devices(data) {
      this.$data.devices = data;
    },
    message({ devid, data }) {
      const dev = this.$data.sceneDeviceMap.get(devid);
      if (!dev) return;
      this.$data.sceneDeviceMap.set(devid, { ...dev, real_value: data });
      this.$forceUpdate();
      if (dev.type === 'window') {
        this.$data.windowDevice = { ...dev, real_value: data };
      }
    },
    join(dev: ISimpleDevice) {
      this.$data.sceneDeviceMap.set(dev.devid, dev);
      this.$forceUpdate();
      if (dev.type === 'window') {
        this.$data.windowDevice = dev;
      }
    },
    lost(dev: ISceneDevice) {
      this.$edger.notify.error(`${dev.alias}设备丢失！`);
      this.$data.sceneDeviceMap.delete(dev.devid);
      this.$forceUpdate();
      if (dev.type === 'window') {
        this.$data.windowDevice = null;
      }
    },
    delete(dev) {
      this.$data.sceneDeviceMap.delete(dev.devid);
      this.$forceUpdate();
      if (dev.type === 'window') {
        this.$data.windowDevice = null;
      }
    },
    alarm({ devid, value }) {
      const dev = this.$data.sceneDeviceMap.get(devid);
      if (!dev) {
        return this.$edger.notify.warning('数据可能出错，请刷新页面！');
      }
      this.$data.sceneDeviceMap.set(devid, { ...dev, alarm_value: value });
    },
    error(msg) {
      this.$edger.notify.error(msg);
    },
    success(msg) {
      this.$edger.notify.success(msg);
    }
  }
})
export default class Gas extends Vue {
  private showModel = false;
  private alarmModel: { show: boolean; devid: string; alarm_value: number; type: IDeviceType; alias: string } = {
    show: false,
    devid: '',
    type: 'c2h5oh',
    alias: '',
    alarm_value: 0
  };
  private devices: ISimpleDevice[] = [];
  private sceneDeviceMap: Map<string, ISceneDevice> = new Map([]);
  private windowDevice: ISceneDevice | null = null;

  public created() {
    this.$socket.client.emit('init', (data: IInitData) => {
      console.log(data);
    });
  }

  public render() {
    return (
      <div class={style['gas-page']}>
        <h4>智能开窗</h4>
        <div class={style['gas']}>
          <div class={style['gas-window']}>
            <window
              value={this.windowDevice ? this.windowDevice!.real_value : 0}
              disabled={!this.windowDevice}
              on-slide={this.handleSlide}></window>
          </div>
          <h5>
            设备列表
            <div
              class={style['add-button']}
              on-click={() => {
                this.showModel = true;
              }}>
              +
            </div>
          </h5>
          {this.renderDevGroup()}
        </div>

        {this.renderDevModel()}
        {this.renderGasDevAlarmModel()}
      </div>
    );
  }

  private renderDevGroup() {
    return (
      <div class={style['gas-list']}>
        <div class={style['gas-list-content']}>
          {[...this.sceneDeviceMap.values()].map(item => {
            return (
              <van-swipe-cell stop-propagation>
                <div class={style['gas-list-item']}>
                  <div class={style['gas-list-item-left']}>
                    <img src={item.type === 'window' ? windowIconPng : gasPng} alt='' srcset='' />
                    <div>{item.alias}</div>
                  </div>
                  <div class={style['gas-list-item-right']}>
                    {item.type === 'window' ? (
                      <span
                        style={{
                          'font-size': '15px',
                          color: item.real_value > 0 ? '#4976ff' : '#999'
                        }}>
                        {item.real_value > 0 ? `已开启${item.real_value}%` : '已关闭'}
                      </span>
                    ) : (
                      // <van-switch
                      //   size='20'
                      //   value={item.real_value > 0}
                      //   active-color='#4976ff'
                      //   inactive-color='#b0b0b0'
                      //   on-change={(v: boolean) => this.handleSlide(v ? 'right' : 'left')}
                      // />
                      <span
                        style={{
                          color: item.real_value > item.alarm_value! ? '#ee0a24' : '#4976ff'
                        }}>
                        {item.real_value}
                      </span>
                    )}
                  </div>
                </div>
                <template slot='right'>
                  {item.type !== 'window' && (
                    <van-button
                      type='info'
                      icon='edit'
                      style={{ height: '100%' }}
                      square
                      on-click={() => this.showAlarmValueModel(item)}
                    />
                  )}
                  <van-button
                    type='danger'
                    icon='delete-o'
                    style={{ height: '100%' }}
                    square
                    on-click={() => this.deleteDevice(item)}
                  />
                </template>
              </van-swipe-cell>
            );
          })}
        </div>
      </div>
    );
  }

  private renderDevModel() {
    return (
      <van-dialog
        v-model={this.showModel}
        title='选择设备'
        showConfirmButton={false}
        closeOnClickOverlay
        class={style['model']}>
        <div class={style['model-list']}>{this.renderSelectDevList()}</div>
      </van-dialog>
    );
  }

  private renderGasDevAlarmModel() {
    return (
      <van-dialog
        v-model={this.alarmModel.show}
        title={`设置${this.alarmModel.alias}警告值`}
        showConfirmButton={false}
        closeOnClickOverlay
        class={style['model-alarm']}>
        <div class={style['model-alarm-slider-group']}>
          <div class={[style['model-alarm-slider']]}>
            <van-slider
              v-model={this.alarmModel.alarm_value}
              active-color='#ee0a24'
              step={0.01}
              max={GAS_VALUE_RANGE[this.alarmModel.type][1]}
              min={GAS_VALUE_RANGE[this.alarmModel.type][0]}
              on-drag-end={() => this.changeAlarm()}>
              <template slot='button'>
                <div class={style['custom-button']}>{this.alarmModel.alarm_value}</div>
              </template>
            </van-slider>
          </div>
        </div>
      </van-dialog>
    );
  }

  private renderSelectDevList() {
    return (
      <van-radio-group>
        <van-cell-group>
          {this.devices.map((item: ISimpleDevice) => {
            return (
              <van-cell
                title={item.alias}
                clickable
                // style={{ color: item.join ? '#666' : '#ccc' }}
                on-click={() => {
                  this.addDevice(item);
                }}>
                {/* <van-radio name={item.devid} slot='right-icon' /> */}
                {/* <van-icon name='circle' color='#ccc' size={24} slot='right-icon' /> */}
                {this.sceneDeviceMap.has(item.devid) && (
                  <van-icon name='success' color='#07c160' size={24} slot='right-icon' />
                )}
                {/* {item.join && !this.sceneDeviceMap.has(item.devid) && <van-icon name='warn-o' slot='right-icon' />} */}
              </van-cell>
            );
          })}
        </van-cell-group>
      </van-radio-group>
    );
  }

  // 选择场景设备
  private async addDevice(dev: ISimpleDevice) {
    if (this.sceneDeviceMap.has(dev.devid)) {
      return; // 选中设备为当前已选设备
    }
    if (!this.checkDeviceType(dev)) {
      // 这里目前只有一个窗户
      return this.$edger.notify.warning('请选择正确类型和型号的设备！');
    }
    this.$socket.client.emit('add-scene-device', dev.devid);
    this.showModel = false;
  }

  // 删除场景设备
  private async deleteDevice(dev: ISceneDevice) {
    this.$socket.client.emit('delete-scene-device', dev.devid);
  }

  // 显示气体设备设置警告值模态框
  private showAlarmValueModel(dev: ISceneDevice) {
    this.alarmModel = {
      show: true,
      devid: dev.devid,
      type: dev.type,
      alias: dev.alias,
      alarm_value: dev.alarm_value || GAS_VALUE_RANGE[dev.type][0]
    };
  }

  private handleSlide(status: 'left' | 'right' | 'OFF') {
    // left 关闭 right 开启
    this.$socket?.client.emit(
      'send-device-info',
      this.windowDevice?.devid,
      { method: 'set', window: status },
      (res: IResponse) => {
        if (!res.result) {
          this.$edger.notify.error(res.message);
        }
      }
    );
  }

  private changeAlarm() {
    const data: any = {
      method: 'set'
    };
    const { devid, alarm_value } = this.alarmModel;
    const dev = this.sceneDeviceMap.get(devid);
    if (!dev) {
      return;
    }
    switch (dev.type) {
      case 'tvoc':
        data.tvoc = alarm_value;
        break;
      case 'co':
        data.co = alarm_value;
        break;
      case 'ch4':
        data.ch4 = alarm_value;
        break;
      case 'c2h5oh':
        data.c2h5oh = alarm_value;
        break;
      case 'ch2o':
        data.ch2o = alarm_value;
        break;
      default:
        return this.$edger.notify.error('程序出现未知错误, 请重试！');
    }
    this.$socket.client.emit('send-device-info', devid, data, (res: IResponse) => {
      if (!res.result) {
        this.$edger.notify.error(res.message);
      } else {
        this.alarmModel.show = false;
      }
    });
  }

  private checkDeviceType(dev: ISimpleDevice) {
    return dev.brand === 'lgzm' && ['co', 'ch2o', 'c2h5oh', 'tvoc', 'ch4', 'window'].includes(dev.type);
  }
}
